/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package chessboard;

import java.awt.Point;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.Geometry;
import javax.media.j3d.Group;
import javax.media.j3d.QuadArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.SpotLight;
import javax.media.j3d.Switch;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TransparencyAttributes;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

/**
 *
 * @author Jedrek
 */
public class HighlightSquare extends TransformGroup{
    
    private Geometry geometry;
    private Appearance appearance;
    private Shape3D square;
    private Switch switchNode;
    Point pPosition;
    SpotLight spotLight;

    /**
     * Constructor
     * @param color color of the square. It will be partly transparrent.
     */
    public HighlightSquare(Color3f color)
    {
        Group group = new Group();
        square = new Shape3D();
        switchNode = new Switch(-1);
        
        geometry = createGeometry();
        square.setGeometry(geometry);
        appearance = createAppearance(color);
        square.setAppearance(appearance);
        
        spotLight = new SpotLight(new Color3f(0.4f*color.x, 0.2f*color.y, 0.4f*color.z), 
                                            new Point3f(0f, 4f, 0f), 
                                            new Point3f(0.1f, 0.1f, 0.1f),
                                            new Vector3f(0f, -1f, 0f),
                                            0.1f,
                                            0.5f);
        
        spotLight.setInfluencingBounds(new BoundingSphere(new Point3d(0, 0, 0), 1000d));
        spotLight.setEnable(true);
        group.addChild(spotLight);
        group.addChild(square);
        
        switchNode.addChild(group);
        switchNode.setCapability(Switch.ALLOW_SWITCH_WRITE);
        this.addChild(switchNode);
        
        this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    }
    
    private Geometry createGeometry()
    {
        QuadArray arr = new QuadArray(4, QuadArray.COORDINATES | QuadArray.NORMALS);
        arr.setCoordinates(0, new Point3f[] {new Point3f(0.5f, 0.01f, 0.5f),
                                             new Point3f(0.5f, 0.01f, -0.5f),
                                             new Point3f(-0.5f, 0.01f, -0.5f),
                                             new Point3f(-0.5f, 0.01f, 0.5f)});
        
        arr.setNormals(0, new Vector3f[] {new Vector3f(0, 1f, 0),
                                          new Vector3f(0, 1f, 0),
                                          new Vector3f(0, 1f, 0),
                                          new Vector3f(0, 1f, 0)});
        
        return arr;
    }
    
    private Appearance createAppearance(Color3f color)
    {
        Appearance ap = new Appearance();
        
        ColoringAttributes ca = new ColoringAttributes();
        ca.setColor(color);
        TransparencyAttributes ta = new TransparencyAttributes(TransparencyAttributes.FASTEST, 0.5f);
        
        ap.setColoringAttributes(ca);
        ap.setTransparencyAttributes(ta);
        
        return ap;
    }

    /**
     * shows or hides square
     * @param bShow
     */
    public void show(boolean bShow)
    {
        if(bShow)
            switchNode.setWhichChild(0);
        else
            switchNode.setWhichChild(-1);
    }

    /**
     * sets square's position. (0, 0) is on A 1
     * @param position new position
     */
    public void setPosition(Point position){
        pPosition = (Point)position.clone();
        Transform3D trans = new Transform3D();
        trans.set(FigureTransformGroup.BoardPos2RealPos(position));
        this.setTransform(trans);
    }

    /**
     * sets square's position. (0, 0) is on A 1
     * @param position new position
     */
    public void setPosition(int x, int y){
        pPosition = new Point(x, y);
        Transform3D trans = new Transform3D();
        trans.set(FigureTransformGroup.BoardPos2RealPos(new Point(x, y)));
        this.setTransform(trans);
    }
    
    /**
     * enables or disables the light
     * @param enable if true then the light will be enabled, if false then disabled
     */
    public void enableLight(boolean enable){
        spotLight.setEnable(enable);
    }
}
